package com.youlu.campus.service.order;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.tencentcloudapi.tci.v20190318.models.Person;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.DeliveryOrderSubMsg;
import com.youlu.campus.entity.VO.req.DeliveryOrderSubMsgMQVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;
import static java.util.Comparator.comparingLong;



@Slf4j
@Service
public class DeliveryOrderSubMsgService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Value("${mq.topic.deliveryOrderSub}")
    private String topic;

    public void initTestSubOrder(){
        List<DeliveryOrderSubMsgMQVO> batchShippingOrderList = new ArrayList<>();
        for(int i=0;i<100;i++){
            DeliveryOrderSubMsgMQVO deliveryOrderSubMsgMQ = new  DeliveryOrderSubMsgMQVO();
            deliveryOrderSubMsgMQ.setOrderNo("main"+IdUtil.getSnowflake().nextIdStr());
            deliveryOrderSubMsgMQ.setSubOrderNo("sub"+IdUtil.getSnowflake().nextIdStr());
            deliveryOrderSubMsgMQ.setLogisticsNo("express"+(i+1));
            deliveryOrderSubMsgMQ.setLogisticsCompany("EMS");
            batchShippingOrderList.add(deliveryOrderSubMsgMQ);
        }
        this.doDeliveryOrderSub(batchShippingOrderList);
    }


    @Async
    public void doDeliveryOrderSub(List<DeliveryOrderSubMsgMQVO> batchShippingOrderList){
        if(CollectionUtils.isEmpty(batchShippingOrderList)){
            return;
        }
        //批量发送，暂不考虑消息内容大于4MB、后期优化先判断是否该订单是否有被订阅，已订阅才被发送
        ArrayList<DeliveryOrderSubMsgMQVO> distinctMsgList = batchShippingOrderList.stream().collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparing(DeliveryOrderSubMsgMQVO::getOrderNo))), ArrayList::new));
        if(CollectionUtils.isEmpty(distinctMsgList)){
            log.error("【订阅发货订单 订阅消息】取重无数据");
            return;
        }
        rocketMQTemplate.asyncSend(topic, distinctMsgList, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
               log.info("【订阅发货信息】发送状态 ->{}",sendResult.getSendStatus());
            }
            @Override
            public void onException(Throwable throwable) {
                log.error("【订阅发货订单 订阅消息】消息失败",throwable);
            }
        });
    }


    public void saveOrderSubMsg(DeliveryOrderSubMsg deliveryOrderSubMsg) {
        String orderNo = deliveryOrderSubMsg.getOrderNo();
        String subTemplateId = deliveryOrderSubMsg.getSubTemplateId();
        String userId = deliveryOrderSubMsg.getUserId();
        if (StringUtils.isAnyBlank(orderNo, subTemplateId)) {
            throw new BusinessException("订阅发货通知参数错误");
        }
        log.info("【订单发货订阅通知】userId->{}|orderNo->{}", userId, orderNo);
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        query.addCriteria(Criteria.where("orderNo").is(orderNo));
        query.addCriteria(Criteria.where("subTemplateId").is(subTemplateId));
        Date now = new Date();
        Update update = new Update();
        update.setOnInsert("createdTime", now);
        update.set("updatedTime", now);
        update.set("appId", deliveryOrderSubMsg.getAppId());
        update.set("activityId", deliveryOrderSubMsg.getActivityId());
        update.set("openId", deliveryOrderSubMsg.getOpenId());
        update.inc("subCount",1L);
        ActivityInfo activityInfo = this.mongoTemplate.findById(deliveryOrderSubMsg.getActivityId(), ActivityInfo.class);
        if(Objects.nonNull(activityInfo)){
            update.set("activityName", activityInfo.getName());
        }
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.upsert(Boolean.TRUE);
        //findAndModifyOptions.returnNew(Boolean.TRUE);
        this.mongoTemplate.findAndModify(query,update,findAndModifyOptions,DeliveryOrderSubMsg.class);
    }
}
